/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package fireescape;

import java.awt.geom.Point2D;
import java.awt.Graphics2D;
import java.awt.geom.Line2D;
import java.util.ArrayList;

/**
 *
 * @author parkA
 */
public class RoomShape {

    private ArrayList<Point2D.Double> points;
    private double X;
    private double Y;
    private double width;
    private double height;
    private double centerX;
    private double centerY;

    public RoomShape(ArrayList<Point2D.Double> points) {
        if (points != null) {
            this.points = points;
            double lowX = points.get(0).getX();
            double highX = points.get(0).getX();
            double lowY = points.get(0).getY();
            double highY = points.get(0).getY();
            for (int i = 1; i < points.size(); i++) {
                double testX = points.get(i).getX();
                double testY = points.get(i).getY();
                if (testX < lowX) {
                    lowX = testX;
                }
                if (testX > highX) {
                    highX = testX;
                }
                if (testY < lowY) {
                    lowY = testY;
                }
                if (testY > highY) {
                    highY = testY;
                }
            }
            X = lowX;
            Y = lowY;
            width = highX - lowX;
            height = highY - lowY;
            centerX = computeAverageX();
            centerY = computeAverageY();
            /*points = new ArrayList<Point2D.Double>();
            if (xPoints.size() != yPoints.size()) {
            System.out.println("points size fail");
            }
            for (int i = 0; i < xPoints.size(); i++) {
            points.add(new Point2D.Double(xPoints.get(i), yPoints.get(i)));
            }*/
        }
    }

    public double computeAverageX() {
        double xTotal = 0;
        for (Point2D.Double point : points) {
            xTotal += point.getX();
        }
        return xTotal / points.size();
    }

    public double computeAverageY() {
        double yTotal = 0;
        for (Point2D.Double point : points) {
            yTotal += point.getY();
        }
        return yTotal / points.size();
    }

    public void draw(Graphics2D g) {
        for (int i = 0; i < points.size() - 1; i++) {
            g.draw(new Line2D.Double(points.get(i), points.get(i + 1)));
        }
        g.draw(new Line2D.Double(points.get(0), points.get(points.size() - 1)));
    }

    public Point2D.Double getPoint(int index) {
        return points.get(index);
    }

    public int numVertices() {
        return points.size();
    }

    public double area() {
        double firstDiagonal = points.get(points.size() - 1).getX() * points.get(0).getY();
        for (int i = 0; i < points.size() - 1; i++) {
            firstDiagonal += points.get(i).getX() * points.get(i + 1).getY();
        }
        double secondDiagonal = points.get(points.size() - 1).getY() * points.get(0).getX();
        for (int i = 0; i < points.size() - 1; i++) {
            secondDiagonal += points.get(i).getY() * points.get(i + 1).getX();
        }
        return Math.abs(firstDiagonal - secondDiagonal) / 2;
    }

    public double getX() {
        return X;
    }

    public double getY() {
        return Y;
    }

    public double getWidth() {
        return width;
    }

    public double getHeight() {
        return height;
    }

    public double getCenterX() {
        return centerX;
    }

    public double getCenterY() {
        return centerY;
    }

    public boolean containsBot(double x, double y) {
        boolean bool1 = this.contains(x, y);
        if (!this.contains(x, y)) {
            return false;
        }
        Point2D.Double point = new Point2D.Double(x, y);
        Point2D.Double point1 = points.get(points.size() - 1);
        Point2D.Double point2 = points.get(0);
        if (FireEscapeGUI.pointToLine(point, point1, point2) < BotAI.botRadius && FireEscapeGUI.inPerpendicularRange(point, point1, point2)) {
            return false;
        }
        for (int i = 1; i < points.size(); i++) {
            point1 = point2;
            point2 = points.get(i);
            if (FireEscapeGUI.pointToLine(point, point1, point2) < BotAI.botRadius && FireEscapeGUI.inPerpendicularRange(point, point1, point2)) {
                return false;
            }
        }
        return true;
    }

    public boolean contains(double x, double y) {
        int count = 0;
        double lowX, highX, lowY, highY, xIntersect;
        Point2D.Double point1 = points.get(points.size() - 1);
        Point2D.Double point2 = points.get(0);
        if (point1.getY() != point2.getY()) {
            lowX = point1.getX();
            highX = point2.getX();
            lowY = point1.getY();
            highY = point2.getY();
            if (point2.getX() < lowX) {
                lowX = point2.getX();
                highX = point1.getX();
            }
            if (point2.getY() < lowY) {
                lowY = point2.getY();
                highY = point1.getY();
            }
            if (y >= lowY && y <= highY) {
                xIntersect = (point2.getX() - point1.getX()) / (point2.getY() - point1.getY()) * (y - point1.getY()) + point1.getX();
                //System.out.println(xIntersect + " " + point1 + " " + point2);
                if (x <= xIntersect) {
                    count++;
                }
            }
        }
        for (int i = 1; i < points.size(); i++) {
            point1 = point2;
            point2 = points.get(i);
            if (point1.getY() != point2.getY()) {
                lowX = point1.getX();
                highX = point2.getX();
                lowY = point1.getY();
                highY = point2.getY();
                if (point2.getX() < lowX) {
                    lowX = point2.getX();
                    highX = point1.getX();
                }
                if (point2.getY() < lowY) {
                    lowY = point2.getY();
                    highY = point1.getY();
                }
                if (y >= lowY && y <= highY) {
                    xIntersect = (point2.getX() - point1.getX()) / (point2.getY() - point1.getY()) * (y - point1.getY()) + point1.getX();
                    //System.out.println(xIntersect + " " + point1 + " " + point2);
                    if (x <= xIntersect) {
                        count++;
                    }
                }
            }
        }
        return count % 2 == 1;
    }

    public double minDistanceToWall(double x, double y) {
        double distance = Double.POSITIVE_INFINITY;
        Point2D.Double point = new Point2D.Double(x, y);
        Point2D.Double point1 = points.get(points.size() - 1);
        Point2D.Double point2 = points.get(0);
        if (FireEscapeGUI.inPerpendicularRange(point, point1, point2)) {
            distance = FireEscapeGUI.pointToLine(point, point1, point2);
        }
        for (int i = 1; i < points.size(); i++) {
            point1 = point2;
            point2 = points.get(i);
            if (FireEscapeGUI.inPerpendicularRange(point, point1, point2)) {
                double newDistance = FireEscapeGUI.pointToLine(point, point1, point2);
                if (newDistance < distance) {
                    distance = newDistance;
                }
            }
        }
        return distance;
    }

    public String toString() {
        return "X: " + getX() + " Y: " + getY() + " Width: " + getWidth() + " Height: " + getHeight();
    }
}
